package com.aliang.shopping.util.excel.listener;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aliang.shopping.model.converter.AdminConverter;
import com.aliang.shopping.model.dto.admin.AdminImportDTO;
import com.aliang.shopping.model.po.Admin;
import com.aliang.shopping.service.AdminService;
import com.aliang.shopping.util.InputDataUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
public class AdminImportListener extends MyAnalysisEventListener<AdminImportDTO> {

    // 有效条数
    private int validCount;

    // 无效条数
    private int invalidCount;

    // 导入返回信息
    StringBuilder msg = new StringBuilder();

    private final AdminConverter adminConverter;
    private final AdminService adminService;
    /**
     * 每隔100条存储数据库，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    private final List<AdminImportDTO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public AdminImportListener(AdminConverter adminConverter, AdminService adminService) {
        super();
        this.adminConverter = adminConverter;
        this.adminService = adminService;
    }

    @Override
    public void invoke(AdminImportDTO adminImportDTO, AnalysisContext analysisContext) {
        log.info("解析到一条用户数据:{}", JSONUtil.toJsonStr(adminImportDTO));
        // 校验数据
        StringBuilder validationMsg = new StringBuilder();
        // 必要字段非空校验
        if (StrUtil.hasBlank(adminImportDTO.getUsername(), adminImportDTO.getPassword(), adminImportDTO.getNickname())) {
            validationMsg.append("缺少参数");
        }
        //手机号校验
        if (StrUtil.isBlank(adminImportDTO.getPhone()) || !Validator.isMobile(adminImportDTO.getPhone())) {
            validationMsg.append("手机号不合法。");
        }
        // 邮箱合法性校验
        if (StrUtil.isBlank(adminImportDTO.getEmail()) || !Validator.isEmail(adminImportDTO.getEmail())) {
            validationMsg.append("邮箱不合法。");
        }
        // 管理员类型合法性校验
        if (!InputDataUtil.strIsOK(adminImportDTO.getTypeNum(), "普通管理员", "超级管理员")) {
            validationMsg.append("管理员类型不合法。");
        }
        // 性别合法性校验
        if (!InputDataUtil.strIsOK(adminImportDTO.getSex(), "男", "女")) {
            validationMsg.append("性别不合法。");
        }
        // 数据有效，累加有效条数
        if (validationMsg.length() <= 0) {
            validCount++;
            // 暂存至缓冲区
            cachedDataList.add(adminImportDTO);
            //缓存区数据超过最大存储数量，存入数据
            if (cachedDataList.size() >= BATCH_COUNT) {
                saveData();
            }
        } else {
            invalidCount++;
            msg.append("第").append(validCount + invalidCount).append("行数据校验失败：").append(validationMsg).append("<br/>");
        }
    }


    /**
     * 所有数据解析完成会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //最后的数据还要保存
        if (cachedDataList.size() > 0) {
            saveData();
        }
        log.info("所有数据解析完成！");
    }

    /**
     * 批量插入数据库操作
     */
    private void saveData() {
        //转换数据
        List<Admin> list = this.adminConverter.toPoListByImportDTOList(cachedDataList);
        this.adminService.saveBatch(list);
        // 清空数据
        cachedDataList.clear();
    }

    @Override
    public String getMsg() {
        // 总结信息
        return StrUtil.format("导入结束：成功{}条，失败{}条；<br/>{}", validCount, invalidCount, msg);
    }
}
